package kayao.client.scene;

import kayao.client.network.message.KingRequestMessage;
import kayao.client.network.message.MessageHandler;
import kayao.client.network.message.UnSubscribeMessage;
import kayao.common.KayaoValues;

public class AreaManager {
	private static Region[] sRegions;
	private static int sCurrentRegion = 0;
	//	public static final int NUMBER_OF_AREAS = 4;
	//	private static boolean[] sSubscribedAreas = new boolean[NUMBER_OF_AREAS];
	private static int sSubscribedAreasCounter = 0;
	private static boolean sUpdated = false;
	private static boolean sRegionsUpdated = false;

	public static void initialize() {
		// Calculate number of regions
		if (KayaoValues.NUM_REGIONS_X == 1) { KayaoValues.NUMBER_OF_KINGDOMS = KayaoValues.NUM_REGIONS_Y; }
		else if (KayaoValues.NUM_REGIONS_X % 2 == 0) { KayaoValues.NUMBER_OF_KINGDOMS = (KayaoValues.NUM_REGIONS_X/2) * KayaoValues.NUM_REGIONS_Y + (KayaoValues.NUM_REGIONS_X/2) * (KayaoValues.NUM_REGIONS_Y+1); }
		else { KayaoValues.NUMBER_OF_KINGDOMS = (KayaoValues.NUM_REGIONS_X/2+1) * KayaoValues.NUM_REGIONS_Y + (KayaoValues.NUM_REGIONS_X/2) * (KayaoValues.NUM_REGIONS_Y+1); }
		// Create an array to store the regions
		sRegions = new Region[KayaoValues.NUMBER_OF_KINGDOMS];
		// Now create the regions
		float width;
		float height;
		int counter = 0;
		for (int i = 0; i < KayaoValues.NUM_REGIONS_X; i++) {
			// column 0 2 4 etc..
			if (i % 2 == 0){
				for (int j = 0; j < KayaoValues.NUM_REGIONS_Y; j++) {				
					width = KayaoValues.TOTAL_MAP_WIDTH/KayaoValues.NUM_REGIONS_X;
					height = KayaoValues.TOTAL_MAP_HEIGHT/KayaoValues.NUM_REGIONS_Y;
					sRegions[counter] = new Region(i*width, j*height, (i+1)*width, (j+1)*height);
					counter++;
				}
				// column 1 3 5 etc..
			} else {
				for (int j = 0; j < (KayaoValues.NUM_REGIONS_Y+1); j++) {
					width = KayaoValues.TOTAL_MAP_WIDTH/KayaoValues.NUM_REGIONS_X;
					height = KayaoValues.TOTAL_MAP_HEIGHT/(KayaoValues.NUM_REGIONS_Y);						
					// first region
					if (j == 0){
						sRegions[counter] = new Region(i*width, j*height, (i+1)*width, height/2);
						// last region
					} else if (j == KayaoValues.NUM_REGIONS_Y){
						sRegions[counter] = new Region(i*width, (j-1)*height+height/2, (i+1)*width, j*height);
						// regions in between
					} else {
						sRegions[counter] = new Region(i*width, (j-1)*height+height/2, (i+1)*width, j*height+height/2);
					}
					counter++;
				}
			}
		}
	}

	public static void terminate() {
		sRegions = null;
	}
	
	public static void interesstingRegionsByCord(float x, float y){
		// Check all four corners of the interest box against each region
		//		System.out.println(x + " " + y);

		for (int i=0; i<sRegions.length; i++){
			if (sRegions[i].isIntersecting(x, y)){
				if (sCurrentRegion != i) {
					sCurrentRegion = i;
					sRegionsUpdated = true;
				}
			}
			if (!sRegions[i].isSubscribed()) {
				if (sRegions[i].isIntersecting((x-KayaoValues.INTEREST_BOX), (y-KayaoValues.INTEREST_BOX))){
					sRegions[i].subscribe();
					sRegionsUpdated = true;
					continue;
				}
				if (sRegions[i].isIntersecting((x-KayaoValues.INTEREST_BOX), (y+KayaoValues.INTEREST_BOX))){
					sRegions[i].subscribe();
					sRegionsUpdated = true;
					continue;
				}
				if (sRegions[i].isIntersecting((x+KayaoValues.INTEREST_BOX), (y-KayaoValues.INTEREST_BOX))){
					sRegions[i].subscribe();
					sRegionsUpdated = true;
					continue;
				}
				if (sRegions[i].isIntersecting((x+KayaoValues.INTEREST_BOX), (y+KayaoValues.INTEREST_BOX))){
					sRegions[i].subscribe();
					sRegionsUpdated = true;
					continue;
				}
			} else {
				if (sRegions[i].isIntersecting((x-KayaoValues.INTEREST_BOX), (y-KayaoValues.INTEREST_BOX))){
					continue;
				}
				if (sRegions[i].isIntersecting((x-KayaoValues.INTEREST_BOX), (y+KayaoValues.INTEREST_BOX))){
					continue;
				}
				if (sRegions[i].isIntersecting((x+KayaoValues.INTEREST_BOX), (y-KayaoValues.INTEREST_BOX))){
					continue;
				}
				if (sRegions[i].isIntersecting((x+KayaoValues.INTEREST_BOX), (y+KayaoValues.INTEREST_BOX))){
					continue;
				}
				
				sRegions[i].unSubscribe();
				// If i am not the king
				if (!AoIManager.amIKingInRegion(i)){
					if (AoIManager.getKingByID(i)!=null){
						System.out.println("[AreaManager]: Sending unsubscribe msg to the king (id: "+AoIManager.getKingByID(i)+" of region "+i);
						AoIManager.printKingInfo("[AreaManager]:  Before remove interest in kingdom");
						//remove messages in queue
						MessageHandler.removeSubscriptionFromQueues(AoIManager.getKingByID(i));
						MessageHandler.insertOutgoingMessage(new UnSubscribeMessage(AoIManager.getKingByID(i)));
						AoIManager.removeKingdom(i);
						AoIManager.printKingInfo("[AreaManager]:  After remove interest in kingdom");
						
					} else {
						System.out.println("[AreaManager]: Not king in region, region is empty"+i);
					}
				}
				sRegionsUpdated = true;
			}
		}
		// Now check if there where any updates on which regions we are interessted in
		if (sRegionsUpdated){
			// If there are updates, send a new king request
			System.out.println("[AreaManager]: regions updated -> new king req");
			MessageHandler.insertOutgoingMessage(new KingRequestMessage(KayaoValues.SERVER_IP));
			sRegionsUpdated = false;
		}
	}

	public static void printRegionInfo(){
		System.out.println("!AreaManager.printRegionInfo");
		for(int i=0; i<sRegions.length; i++){
			System.out.println("!region "+i+" subscribed: "+sRegions[i].isSubscribed());
		}
		System.out.println("!-----------------------");
	}
	
	public static void subscribeArea(int region) {
		sRegions[region].subscribe();
		sSubscribedAreasCounter++;
		sUpdated = true;
	}

	public static void unsubscribeArea(int region) {
		sRegions[region].unSubscribe();
		sSubscribedAreasCounter--;
		sUpdated = true;
	}

	public static void setCurrentRegion(int region) {
		sCurrentRegion = region;
	}

	public static int getCurrentRegion() {
		return sCurrentRegion;
	}

	public static Region[] getSubscribedRegions() {
		return sRegions;
	}

	public static int getSubscribedAreasCount() {
		sSubscribedAreasCounter = 0;
		for (int i = 0; i < sRegions.length; i++) {
			if (sRegions[i].isSubscribed()) {
				sSubscribedAreasCounter++;
			}
		}
		return sSubscribedAreasCounter;
	}

	public static void setUpdated(boolean updated) {
		sUpdated = updated;
	}

	public static boolean isUpdated() {
		return sUpdated;
	}
}
